/**
 * 获取元素dataset兼容处理
 * @param {DOM} el 元素节点
 * @param {String} name 属性名称
 */
export const getDataSet = (el, name) => {
  let rep = new RegExp("-([a-z])", "gi");
  let nameStr =
    typeof name === "string"
      ? name.replace(rep, (all, letter) => letter.toUpperCase())
      : "";
  if (el.dataset) {
    return nameStr ? el.dataset[nameStr] : el.dataset;
  } else {
    let attrs = el.attributes,
      dataset = {},
      reg = new RegExp("^data-(.+)"),
      repReg = new RegExp("-([a-z])", "gi");
    attrs.forEach((value) => {
      let matchStr = value.name.match(reg);
      if (matchStr) {
        name = matchStr[1].replace(repReg, (all, letter) =>
          letter.toUpperCase()
        );
        dataset[name] = value.value;
      }
    });
    return nameStr ? dataset[nameStr] : dataset;
  }
};

/**
 * 设置dataset属性兼容方法
 * @param {DOM} el 元素节点
 * @param {String/Object} name 属性名称/需要设置的属性的对象集合
 * @param {String} value 属性值
 */
export const setDataSet = (el, name, value) => {
  if (typeof name === "string") {
    if (el.dataset) {
      el.dataset[name] = value;
    } else {
      let reg = new RegExp("([A-Z])", "g");
      let attr =
        "data-" +
        name.replace(reg, (match, letter) => "-" + letter.toLowerCase());
      el.attributes[attr] = value;
    }
  } else if (typeof name === "object") {
    for (let [k, v] of Object.entries(name)) {
      setDataSet(el, k, v);
    }
  }
};

/**
 * 检测节点所处路由区域
 * @param {Object(VUE)} context Vue实例对象
 *
 * @returns Number/String 节点所处路由层级、输出字符串时，接点处于routeview外
 */
export const checkRouteViewDepath = (context) => {
  let parent = context;
  let routeDepath = "public";
  let routeObj = { routeDepath, routeVpath: "", routerEl: null };
  while (parent && parent.$vnode) {
    if (parent.$vnode.data.routerView) {
      routeDepath = parent.$vnode.data.routerViewDepth;
      break;
    } else {
      parent = parent.$parent;
    }
  }
  routeObj.routerEl = () => parent.$el;
  if (parent.$parent) {
    routeObj.routeDepath = routeDepath;
    let list = [];
    context.$route.matched.forEach((value, key) => {
      key <= routeDepath ? list.push(value.name) : null;
    });
    routeObj.routeVpath = list.join(":::");
  }
  return routeObj;
};

/**
 * 计算节点位置信息
 * @param {DOM HTMLelement} el DOM节点
 * @param {String} key top、left
 */
export const getOffsetParent = (el, key) => {
  let offset = 0;
  var str = key.replace(/^([a-z])(.+)/, (match, a, b) => a.toUpperCase() + b);
  for (let parent = el; parent; parent = parent.offsetParent) {
    offset += parent["offset" + str];
  }
  return offset;
};

/**
 * 为对象属性添加代理
 * @param {Object} base 焦点元素对象
 * @param {String} key 方向
 */
export const instancePosition = (base, key) => {
  let el = base.elem;
  Object.defineProperty(base, key, {
    get() {
      if (key === "width") {
        return el.offsetWidth;
      } else if (key === "height") {
        return el.offsetHeight;
      } else {
        return getOffsetParent(el, key);
      }
    },
  });
};

/**
 * 检测对象是否含有对应的属性
 * @param {Object} obj 查询对象
 * @param {String} attr 查询属性
 * @returns Boolean 判断对象是否含有该属性
 */
export const hasOwn = (obj, attr) =>
  Object.prototype.hasOwnProperty.call(obj, attr);

export default {
  hasOwn,
  getDataSet,
  setDataSet,
  checkRouteViewDepath,
  getOffsetParent,
  instancePosition,
};
